<template>
  <div class="virtual-container" ref="container" @scroll="onScroll">
    <div :style="heightStyle" class="virtual-container__layout"></div>
    <div class="virtual-container__show" :style="transformStyle">
      <div class="virtual-is-ref" ref="client">
        <div
          v-for="(item, index) in listViews"
          :key="item.id"
          :class="['view-item', 'line-'.concat(item.id)]"
        >
          <span>{{ item.id }}</span> - <span>{{ item.name }}</span>
          <div>
            <span>{{ item.words }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
const bufferVal = 5;
const all = 50;
import * as utils from "@/utils/index.js";

export default {
  name: "core-virtual",
  data() {
    return {
      scrollTop: 0,
      visibleCount: 20,
      start: 0,
      itemHeight: 100,
      hgValEl: 0,
      dataState: utils.listCreate(all),
    };
  },
  computed: {
    heightStyle() {
      const hgVal = this.itemHeight;
      return {
        width: "100%",
        height: `${hgVal * all}px`,
      };
    },
    listViews() {
      const fnVal = this.start + this.visibleCount;
      const start = this.start - bufferVal;
      return this.dataState.slice(start < 0 ? 0 : start, fnVal);
    },
    transformStyle() {
      return {
        transform: `translateY(${this.scrollTop}px)`,
      };
    },
    padStanVal() {
      return this.itemHeight * 5;
    },
  },
  mounted() {
    this.getIndexState();
    this.computeClient();
  },
  methods: {
    onScroll(e) {
      const scrollTop = e.target.scrollTop;
      const startVal = ~~(scrollTop / this.itemHeight);
      const isUpScroll = this.scrollTop - scrollTop >= 0;
      // 满足条件的向下滚动 或 向上滚动
      if (this.start + this.visibleCount < all || isUpScroll) {
        const absVal = scrollTop - this.scrollTop;
        this.start = startVal;
        let upScrollVal = scrollTop - this.padStanVal;
        upScrollVal = upScrollVal <= 0 ? 0 : upScrollVal;

        if (Math.abs(absVal) >= this.padStanVal || isUpScroll) {
          this.scrollTop = isUpScroll ? upScrollVal : scrollTop;
          console.log("---------------", this.padStanVal);
          console.log("Math.abs", this.scrollTop, absVal);
        }
        console.log("scrollTop", this.start, scrollTop);
      }
    },
    getIndexState() {
      const len = this.dataState.length;
      console.log("length", len);
      console.log(this.dataState);
    },
    computeClient() {
      const hel = this.$refs.client;
      const rect = hel.getBoundingClientRect();
      const hgVal = rect.height / this.visibleCount;
      // 0.8 系修正系数，避免滚动到底时最后一屏数据出现空白的情况
      this.itemHeight = ~~hgVal * 0.8;
      // console.log("client rect", hgVal, rect);
    },
  },
};
</script>

<style lang="scss" scoped>
.virtual-container {
  overflow-y: scroll;
  height: 400px;
  position: relative;
  border: 3px solid red;

  &__show {
    position: absolute;
    inset: 0;
    z-index: 90;
    // overflow: hidden;
  }
}

.view-item {
  line-height: 40px;
}
</style>
